package pt.isel.pdm.ouryamba;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.os.Bundle;
import android.view.MenuItem;

/**
 * Represents the base class for general Activities</br>
 * 
 * Contains the common methods to multiple Activities like the listener for preferences changes
 * and the actions to take on each click over each menu item.  
 * */
@SuppressLint("Registered")
public class BaseActivity extends Activity implements OnSharedPreferenceChangeListener
{
	protected General app;
	private AlertDialog alertDialog;
	
	
//Own methods
	
	/**
	 * Display an alert dialog on the screen saying the preferences need to be filled.</br>
	 * 
	 * Since the dialog content is static (won't change) the dialog is only build once and could
	 * be shown many times. With this design it won't waste resources (this case is time resource). 
	 */
	protected final void showLoginConfigAlertDialog()
	{
		if(alertDialog == null)
		{
			final class DummyListener implements DialogInterface.OnClickListener
			{
				@Override
				public void onClick(DialogInterface dialog, int which) 
				{
					switch(which)
					{
						case DialogInterface.BUTTON_POSITIVE:
							startActivity(new Intent(BaseActivity.this.getApplicationContext(), PreferencesActivity.class));
							break;
						case DialogInterface.BUTTON_NEGATIVE:
							finish();
							break;
					}
					dialog.dismiss();
				}
			};
			DummyListener dl = new DummyListener();
			AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
			alertDialogBuilder.setTitle(R.string.configErrorDialgTitle);
			alertDialogBuilder.setMessage(R.string.configErrorDialgMessage);
			alertDialogBuilder.setPositiveButton(R.string.preferences, dl);
			alertDialogBuilder.setNegativeButton(R.string.configErrorDialgNegButton, dl);
			alertDialog = alertDialogBuilder.create();
			alertDialog.setCancelable(false);
		}
		alertDialog.show();	
	}

	
//Activity methods
	
	/**
	 * Initialize the common variables for children activities. </br>
	 * 
	 * Initialize the {@code app} variable with a reference for General class.
	 * Also register the listener for the variable {@code prefs} that exists in {@code app}. This 
	 * affection is done here because this class is the one that will serve as listener for every
	 * change made in preferences.
	 * */
	@Override
	public void onCreate(Bundle savedInstanceState) 
	{
		super.onCreate(savedInstanceState);
		app = (General) getApplication();
		app.prefs.registerOnSharedPreferenceChangeListener(this);
	}
		
	/**
	 * Check if the preferences are filled before showing any children activities.
	 * If the preferences are not filled, is shown an dialog with an alert message.</br>
	 * 
	 * Call the method {@code assertPreferences()} that exist in General class to check if the preferences
	 * are filled and if don't, call the method {@code showLoginConfigAlertDialog()} that exist in this
	 * class, to show the alert dialog.</br>
	 * 
	 * This is to prevent the user from doing actions in activities that need some preferences
	 * that actually don't exist.
	 * 
	 * @see General#assertPreferences()
	 * @see #showLoginConfigAlertDialog()
	 * */
	@Override
	public void onResume()
	{
		super.onResume();
		if(!app.assertPreferences())
		{
			showLoginConfigAlertDialog();
		}
	}
	
	/**
	 * Delegate the behavior for each menu item when it's clicked.</br>
	 * 
	 * When the item clicked is the preferences option, the action is to open the PreferencesActivity.</br>
	 * 
	 * When the item clicked is the user info option, the action is to open the UserInfoActivity.
	 * However, we added the flag {@code FLAG_ACTIVITY_REORDER_TO_FRONT} to the intent to avoid
	 * creating multiple activities of the same type. With this, if an activity is already in the
	 * background of this back stack, the desired activity will be brought to front instead of being
	 * created again.</br>
	 * 
	 * When the item clicked is the timeline option, the action is to open the TimelineActivity.
	 * However, we added the flag {@code FLAG_ACTIVITY_REORDER_TO_FRONT} to the intent to avoid
	 * creating multiple activities of the same type. With this, if an activity is already in the
	 * background of this back stack, the desired activity will be brought to front instead of being
	 * created again.</br>
	 * 
	 * When the item clicked is the status option, the action is to open the StatusActivity.
	 * However, we added the flag {@code FLAG_ACTIVITY_REORDER_TO_FRONT} to the intent to avoid
	 * creating multiple activities of the same type. With this, if an activity is already in the
	 * background of this back stack, the desired activity will be brought to front instead of being
	 * created again.
	 * */
    @Override
	public boolean onOptionsItemSelected(MenuItem item) 
    {
		switch(item.getItemId())
		{
			case R.id.action_preferences:
				startActivity(new Intent(this, PreferencesActivity.class));
				return true;
			case R.id.action_userInfo:
				startActivity(new Intent(this, UserInfoActivity.class)
					.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT));
				return true;
			case R.id.action_timeline:
				startActivity(new Intent(this, TimelineActivity.class)
					.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT));
				return true;
			case R.id.action_status:
				startActivity(new Intent(this, StatusActivity.class)
					.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT));
				return true;
			default:
				return super.onOptionsItemSelected(item);
		}
	}	

    
//OnSharedPreferenceChangeListener methods

	/**
     * Delegate the behavior when some preference had changed.</br>
     * 
     * When the preference changed was the password or API URL, the action will be reset
     * the {@code twitter} variable of the General class. It resets the variable (set it to null)
     * because it have to be created again with the new values that have being changed.</br>
     * 
     * When the preference changed was the user name, the action will be reset the {@code username}
     * variable of the General class. This reset also resets the {@code twitter} variable. It resets
     * the variables (set it to null) because it have to be created again with the new values that 
     * have being changed.</br>
     * 
     * When the preference changed was the maximum number of characters allowed in the status
     * message, the action will be reset the variable {@code maxChars} of the General class. It 
     * resets the variable (set it to null) because this way indicates that the value should be
     * fetched again from the preferences.</br>
     * 
     * When the preference changed was the maximum number of messages to show in the timeline, the
     * action will be reset the variable {@code maxMsgToShow} of the General class. It resets the 
     * variable (set it to null) because this way indicates that the value should be fetched again
     * from the preferences.</br>
     * 
     * When the preference changed was the maximum number of messages to store in the timeline 
     * private list, the action will be reset the variable {@code maxMsgStored} of the General class.
     * It resets the variable (set it to null) because this way indicates that the value should be 
     * fetched again from the preferences.</br>
     * 
     * When the preference changed was the interval of the automatic updates, the action will be 
     * reset the variable {@code automaticUpdateInterval} of the General class.
     * It resets the variable (set it to zero) because this way indicates that the value should be 
     * fetched again from the preferences.</br>
     * 
     * When the preference changed was the switch that enables/disables the automatic updates of the
     * timeline private list of statuses, the action will depend on the new value. If the new value
     * of the preference is to enable the automatic update, we enable the automatic update. This is
     * enough to start the process because it uses the variable {@code automaticUpdateInterval} which
     * indicates what we described earlier and also indicates whether or not the automatic updates are
     * enabled or not.
     * If the preference is set to disable, we will disable the automatic updates (stop the process)
     * and we call the {@code resetAutomaticUpdate} method to indicate the automatic updates are 
     * disabled.</br>
     * 
     * @see General#resetTwitter()
     * @see General#resetUsername()
     * @see General#resetMaxChars()
     * @see General#resetMaxMsgToShow()
     * @see General#resetMaxMsgStored()
     * @see General#resetAutomaticUpdateInterval()
     * @see General#resetAutomaticUpdate()
     * */
	@Override
	public void onSharedPreferenceChanged(SharedPreferences prefs, String key)
	{
		if(key.equals(General.PASSWORD_PREF_KEY) || key.equals(General.URL_PREF_KEY))
		{
			app.resetTwitter();
		}
		else if(key.equals(General.USER_PREF_KEY))
		{
			app.resetUsername();
		}
		else if(key.equals(General.STATUS_LENGTH_PREF_KEY))
		{
			app.resetMaxChars();
		}
		else if(key.equals(General.MSG_NUMBER_TO_SHOW_PREF_KEY))
		{
			app.resetMaxMsgToShow();
		}
		else if(key.equals(General.MSG_NUMBER_TO_STORE_PREF_KEY))
		{
			app.resetMaxMsgStored();
			app.resetTwitter();
		}
		else if(key.equals(General.AUTOMATIC_UPDATE_PERIOD_PREF_KEY))
		{
			app.resetAutomaticUpdateInterval();
		}
		else if(key.equals(General.AUTOMATIC_UPDATE_PREF_KEY))
		{
			boolean start = prefs.getBoolean(key, false);
			Intent updaterIntent = new Intent(this, TimelinePullService.class);
			if(start)
			{
				updaterIntent.putExtra(TimelinePullService.ARG_ACTION_TYPE, TimelinePullService.ARG_START_AUTOMATIC_UPDATE);
			}
			else
			{
				app.resetAutomaticUpdate();
				updaterIntent.putExtra(TimelinePullService.ARG_ACTION_TYPE, TimelinePullService.ARG_STOP_AUTOMATIC_UPDATE);
			}
			startService(updaterIntent);
			updaterIntent = null;
		}
	}

}
